﻿/**
@file
    diehard_text_editor.js
@brief
    Copyright 2009 Creative Crew. All rights reserved.
@author
    William Chang
    Email: william@babybluebox.com
    Website: http://www.babybluebox.com
@version
    0.2
@date
    - Created: 2008-09-10
    - Modified: 2009-04-23
    .
@note
    Prerequisites:
    - jQuery http://www.jquery.com/
    - TinyMCE http://tinymce.moxiecode.com/
    .
    References:
    - General:
        - http://tinymce.moxiecode.com/
        - http://wiki.moxiecode.com/index.php/TinyMCE:Commands
        - http://hamisageek.blogspot.com/2007/11/multiple-tinymce-3-instances-on-one.html
        .
    - Validation:
        - http://tinymce.moxiecode.com/punbb/viewtopic.php?id=27
        .
    - HTML encode and decode:
        - http://tinymce.moxiecode.com/punbb/viewtopic.php?id=9587
        .
    - Dynamic load CSS:
        - http://tinymce.moxiecode.com/punbb/viewtopic.php?id=6697
        - http://wiki.moxiecode.com/index.php/TinyMCE:Configuration/content_css
        .
    - Template:
        - http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/template
        .
    - Auto saving:
        - http://webnv.net/articles/autosaving-with-jquery-and-tinymce
        .
    .
*/

/** Text editor widget. */
function classTextEditor(strRegionId, strInputTextId, strContentCssUrl, strTemplateJavascriptUrl) {
    var memberPublic = this;
    memberPublic.init = init;
    memberPublic.loadTextEditor = loadTextEditor;
    memberPublic.unloadTextEditor = unloadTextEditor;
    memberPublic.getContent = getContent;
    memberPublic.setContent = setContent;
    memberPublic.stripHtmlTags = stripHtmlTags;
    memberPublic.encodeHtml = encodeHtml;
    memberPublic.decodeHtml = decodeHtml;
    memberPublic.strRegionId = strRegionId;
    memberPublic.strInputTextId = strInputTextId;
    memberPublic.strContentCssUrl = strContentCssUrl;
    memberPublic.strTemplateJavascriptUrl = strTemplateJavascriptUrl;
    var _eleRegion, _eleInputText;
    var _objTextEditorConfigs = [];
    var _isLoaded, _isDirty;
    
    /** Load text editor. */
    function loadTextEditor() {
        tinyMCE.settings = _objTextEditorConfigs[0];
        tinyMCE.execCommand('mceAddControl', false, strInputTextId);
        tinymce.addUnload(_onEditorUnload);
        _isLoaded = true;
    }
    /** Unload text editor. */
    function unloadTextEditor() {
        if(_isLoaded) {
            tinyMCE.execCommand('mceRemoveControl', false, strInputTextId);
            _setEvents();
            tinymce.removeUnload(_onEditorUnload);
            _isLoaded = false;
        }
        $(_eleInputText).val('');
    }
    /** On editor event, unload. */
    function _onEditorUnload() {
        if(_isDirty) {
            $(_eleInputText).val(encodeHtml($(_eleInputText).val()));
        }
    }
    /** On editor event, submit. */
    function _onEditorSubmit(ed, e) {}
    /** On editor event, save content. */
    function _onEditorSaveContent(ed, o) {
        o.content = encodeHtml(o.content);
        _isDirty = false;
    }
    /** On editor event, load content. */
    function _onEditorLoadContent(ed, o) {
        ed.focus();
    }
    /** On editor event, set content. */
    function _onEditorSetContent(ed, o) {}
    /** On editor event, before set content. */
    function _onEditorBeforeSetContent(ed, o) {
        if(o.source_view === undefined && o.load !== undefined) {
            o.content = decodeHtml(stripHtmlTags(o.content));
            _isDirty = true;
        }
    }
    /** Get content. */
    function getContent() {
        if(tinyMCE.get(strInputTextId) !== undefined) {
            return tinyMCE.get(strInputTextId).getContent();
        } else {
            return $(_eleInputText).val();
        }
    }
    /** Set content. */
    function setContent(str) {
        tinyMCE.get(strInputTextId).setContent(str);
    }
    /** Strip HTML Tags. */
    function stripHtmlTags(str) {
        return str.replace(/<\/?[^>]+>/gi, '');
    }
    /** Encode HTML to prevent Microsoft ASPNET HttpRequestValidationException. */
    function encodeHtml(str) {
        return str.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
    }
    /** Decode HTML. */
    function decodeHtml(str) {
        return str.replace(/&amp;/g,'&').replace(/&lt;/g,'<').replace(/&gt;/g,'>');
    }
    /** Set events. */
    function _setEvents() {
        $('#' + strInputTextId, _eleRegion).unbind('focus').bind('focus', function(e) {
            loadTextEditor();
            $(this).unbind('focus');
        });
    }
    /** Set text editor configurations. */
    function _setTextEditorConfigs() {
        _objTextEditorConfigs = [{
            mode:'none',
            theme:'advanced',
            skin:'o2k7',
            plugins:'inlinepopups,preview,paste,visualchars,template,safari',
            theme_advanced_buttons1:'cut,copy,paste,pastetext,pasteword,|,bullist,numlist,outdent,indent,|,undo,redo,|,link,unlink,|,removeformat,cleanup,|,sub,sup,charmap,|,visualchars,visualaid,code,preview',
            theme_advanced_buttons2:'image,template,|,styleselect,formatselect,|,bold,italic,underline,strikethrough,blockquote,|,justifyleft,justifycenter,justifyright,justifyfull,|,forecolor,backcolor',
            theme_advanced_buttons3:'',
            theme_advanced_toolbar_location:'top',
            theme_advanced_toolbar_align:'left',
            theme_advanced_statusbar_location:'bottom',
            theme_advanced_resizing:true,
            theme_advanced_resize_horizontal:false,
            theme_advanced_source_editor_wrap:false,
            accessibility_focus:false,
            apply_source_formatting:true,
            fix_list_elements:true,
            fix_table_elements:true,
            fix_nesting:true,
            setup:function(ed) {
                ed.onBeforeSetContent.add(_onEditorBeforeSetContent);
                ed.onSetContent.add(_onEditorSetContent);
                ed.onLoadContent.add(_onEditorLoadContent);
                ed.onSaveContent.add(_onEditorSaveContent);
                ed.onSubmit.add(_onEditorSubmit);
            },
            dialog_type:'window',
            content_css:strContentCssUrl,
            template_external_list_url:strTemplateJavascriptUrl,
            invalid_elements:'script,object,applet,iframe'
        }];
    }
    /** Init class. */
    function init() {
        _eleRegion = $('#' + strRegionId).get(0);
        _eleInputText = $('#' + strInputTextId, _eleRegion).get(0);
        _isLoaded = false;
        _isDirty = false;
        _setTextEditorConfigs();
        _setEvents();
    }
}